<?php
function longestSubstring($str) {
    // 记录字符最后一次出现的位置
    $char_pos = array();

    $str_len = strlen($str);

    $curLength = 0; // 记录以当前字符为结尾的最长不重复子字符串长度
    $maxLength = 0; // 记录最长不重复子串长度
    $start = 0;     // 开始位置
    $end = 0;       // 结束位置

    for ($i=0; $i<$str_len; $i++) {
        $case_1 = $case_2 = $case_3 = false;
        // 没有出现过
        if (! isset($char_pos[$str[$i]])) {
            $curLength++;
            $case_1 = true;
            // 如果上一次出现的位置不在当前最长不重复的子串中
        } else if (($i - $char_pos[$str[$i]]) > $curLength) {
            $curLength++;
            $case_2 = true;
        } else {   // 如果上一次出现的位置在当前最长不重复的子串中
            $curLength = $i - $char_pos[$str[$i]];
            $case_3 = true;
        }

        $char_pos[$str[$i]] = $i;

        if ($maxLength < $curLength) {
            $maxLength = $curLength;
            if ($case_1 || $case_2) {
                $end = $i;
                $start = $end - $maxLength + 1;
            } else {
                $end = $i - 1;
                $start = $char_pos[$str[$i]];
            }
        }
    }
    return substr($str, $start, $maxLength);
}
echo longestSubstring('abcdafgce');